package daobeauty.interceptor.invoke.impl;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;

import daobeauty.interceptor.invoke.AbstractCurrentSessionInvokeStrategy;
import daobeauty.interceptor.invoke.ArgumentMask;
import daobeauty.interceptor.returntype.executor.criteria.CriteriaExecutor;
import daobeauty.util.MethodSignatureUtils;

public class FindByExampleInvoke extends AbstractCurrentSessionInvokeStrategy {
	private static final Log LOG = LogFactory.getLog(FindByExampleInvoke.class);
	
	private final CriteriaExecutor executor;
	private final ArgumentMask argumentMask;
	
	@SuppressWarnings("unchecked")
	public FindByExampleInvoke(Method method, SessionFactory sessionFactory, Class domainClass) {
		super(sessionFactory, domainClass);
		final Class [] parameterTypes = method.getParameterTypes();
		if (parameterTypes==null || parameterTypes.length<1 || !domainClass.isAssignableFrom(parameterTypes[0])){
			throw new IllegalArgumentException("method "+MethodSignatureUtils.toMethodSignature(method)+" must have at least one parameter with first parameter of type "+domainClass.getName());
		}
		executor = new CriteriaExecutor(method.getReturnType());
		argumentMask = new ArgumentMask(method, 0);
		
		if (LOG.isInfoEnabled()){
			LOG.info("created findByExample strategy with arguments "+(argumentMask.hasLimiting()?"limiting ":"")+(argumentMask.hasSorting()?"sorting ":"")+"for method "+MethodSignatureUtils.toMethodSignature(method));
		}
	}

	public Object invoke(String methodName, Object[] args) throws Exception {
		if (args[0]!=null){
			return executor.execute(createCriteria().add(Example.create(args[0])), argumentMask.getLimiting(args), argumentMask.getSorting(args));
		}
		return null;
	}
}
